package com.xuqi.W3;

import java.io.IOException;
import java.io.InputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.InflaterInputStream;

/**
 * This class is designed to handle compressed HTTP response body. It will
 * decompress the HTTP body before returning it if it's needed.
 * 
 * IMPORTANT: On Android-2.3 (or maybe higher version), it REQUIRES you to set
 * request header "Accept-Encoding" to make it works correctly.
 * 
 * @author $Author: kuang $
 */
public class W3HttpInputStream extends InputStream
{

	InputStream m_cInputStream = null;
	W3HttpRawInputStream m_cRawInputStream = null;

	/**
	 * Constructor
	 * 
	 * @param rawStream
	 *            : "InputStream" returned by "HttpURLConnection.getInputStream"
	 * @param strEncoding
	 *            : "Content-Encoding" field returned from server.
	 * @throws IOException
	 */
	public W3HttpInputStream(InputStream rawStream, String strEncoding) throws IOException
	{
		super();
		m_cRawInputStream = new W3HttpRawInputStream(rawStream);

		if (null == strEncoding || "identity".equalsIgnoreCase(strEncoding))
		{
			m_cInputStream = m_cRawInputStream;
		}
		else if ("gzip".equalsIgnoreCase(strEncoding))
		{
			m_cInputStream = new GZIPInputStream(m_cRawInputStream);
		}
		else if ("deflate".equalsIgnoreCase(strEncoding))
		{
			m_cInputStream = new InflaterInputStream(m_cRawInputStream);
		}
		else
		{
			// NOTE: NO W3HttpInputStream object will be created in this case.
			throw new IOException(String.format("Content-Encding not supported: %s", strEncoding));
		}
	}

	/**
	 * Get how many raw bytes we have read (before decompression) from socket
	 * for response body.
	 */
	public int getReadRawBytes()
	{
		return m_cRawInputStream.getReadBytes();
	}

	@Override
	public int available() throws IOException
	{
		return m_cInputStream.available();
	}

	@Override
	public void close() throws IOException
	{
		m_cInputStream.close();
	}

	@Override
	public void mark(int pos)
	{
		m_cInputStream.mark(pos);
	}

	@Override
	public boolean markSupported()
	{
		return m_cInputStream.markSupported();
	}

	@Override
	public int read(byte[] b, int offset, int length) throws IOException
	{
		return m_cInputStream.read(b, offset, length);
	}

	@Override
	public int read(byte[] b) throws IOException
	{
		return m_cInputStream.read(b);
	}

	@Override
	public int read() throws IOException
	{
		return m_cInputStream.read();
	}

	@Override
	public void reset() throws IOException
	{
		m_cInputStream.reset();
	}

	@Override
	public long skip(long n) throws IOException
	{
		return m_cInputStream.skip(n);
	}

}
